/*!
\file Action.h
\brief Definition of Action and subclasses.
\ingroup Action
*/

#ifndef ACTION_H
#define ACTION_H

#include"ActionCommunicator.h"

#include<QString>

/*!
\defgroup Action Action Module
This module consists of all Action-related classes.
@{
*/

class Action{
public:
	Action(){ m_isUninteresting = false; }
	//!< Default constructor.
	virtual void exec( ActionCommunicator *communicator ) = 0;
	/*!
	\fn virtual void exec( ActionCommunicator *communicator ) = 0;
	\brief This is where the Action communicates its intentions to the ActionCommunicator.
	Exec is called by Visuzalizer once. It passes its ActionCommunicator, through which the Action can take nearly full control of the interface.
	*/
	
	virtual bool isUninteresting()const{ return m_isUninteresting; }
	//!< Returns wether or not the AlgorithmVisualizer should take a short break after showing this action.
	virtual void setUninteresting( bool uninteresting ){ m_isUninteresting = uninteresting; }
	//!< Set function for isUninteresting.
	virtual ~Action(){}
	//!< Virtual destructor.
protected:
	bool m_isUninteresting;//!< Stores wether or not the visualizer should take a break after processing this Action.
};//!< Action base class. Pure virtual and thus can't be used.

class NodeAction: public Action{
public:
	NodeAction( int nodeID, QString nodeLabel = "" );
	//!< Constructor. Saves basic Node data.
	virtual ~NodeAction(){}
	//!< Destructor.
protected:
	int m_nodeID;//!< ID of Node.
	QString m_nodeLabel;//!< Optional label of Node.
};//!< Virtual base class for Node actions.

class NodeAccessAction: public NodeAction{
public:
	NodeAccessAction( int nodeID );
	//!< Constructor. Takes only nodeID.
	virtual ~NodeAccessAction(){}
	//!< Destructor.
	bool isUninteresting()const{ return true; }
	//!< This type of action is not considered to be interesting, this means the AlgorithmVisualizer may read many of those without halting.
	virtual void exec( ActionCommunicator *communicator );
	//!< exec reimplementation.
private:
};//!< Action to display a Node in Graph has been queried.

class NodeAddAction: public NodeAction{
public:
	NodeAddAction( int nodeID, QString nodeLabel = "", bool isUninteresting = false );
	//!< Constructor. Needs nodeID and nodeLabel to introduce an entirely new Node.
	virtual ~NodeAddAction(){}
	//!< Destructor.
	virtual void exec( ActionCommunicator *communicator );
	//!< Exec reimplementation will inform the Visualizer of the new Node.
// 	virtual bool isUninteresting()const{ return m_isUninteresting; }
};//!< Action to display a node has been added.

class NodeRemoveAction: public NodeAction{
public:
	NodeRemoveAction( int nodeID );
	//!< Constructor. Needs only nodeID to identify the node.
	virtual ~NodeRemoveAction(){}
	//!< Destructor.
	virtual void exec( ActionCommunicator *communicator );
	//!< Exec informs the Visualizer this Node has been removed.
private:

};//!< Action to display a Node has been removed from the Graph.

class NodeHighlightAction: public NodeAction{
public:
	NodeHighlightAction( int nodeID );
	//!< Constructor. Only nodeID is required to identify the Node to be highlighted.
	virtual ~NodeHighlightAction(){}
	//!< Destructor
	virtual void exec( ActionCommunicator *communicator );
	//!< Will ask for given Node to be highlighted.
private:
};//!< Action to highlight a Node.

class NodeUnHighlightAction: public NodeAction{
public:
	NodeUnHighlightAction( int nodeID );
	//!< Constructor. Only nodeID is sufficient to identify the Node to be unhighlighted.
	virtual ~NodeUnHighlightAction(){}
	//!< Destructor
	virtual void exec( ActionCommunicator *communicator );
	//!< Will ask for given Node to be unhighlighted.
private:
};//!< Action to unhighlight a Node.

class EdgeAction: public Action{
public:
	EdgeAction( int edgeID, int from, int to, QString edgeLabel = "" );
	//!< Constructor. Takes all relevant information for an Edge.
	virtual ~EdgeAction(){}
	//!< Destructor.
protected:
	int m_id; //!< ID of Edge.
	int m_from;//!< ID of Node in which Edge starts.
	int m_to;//!< ID of Node in which Edge ends.
	QString m_edgeLabel;//!< Label of Edge.
};//!< Virtual base class for Edge related Actions.

class EdgeAccessAction: public EdgeAction{
public:
	EdgeAccessAction( int edgeID, int from, int to, QString edgeLabel = "" );
	//!< Constructor. Only edgeID should really be necessary, though.
	virtual ~EdgeAccessAction(){}
	//!< Destructor.
	bool isUninteresting()const{ return true; }
	//!< This type of action doesnt need a break.
	virtual void exec( ActionCommunicator *communicator );
	//!< In exec it will inform AlgorithmVisualizer of this access.
private:
};//!< Action to show an Edge in Graph was accessed.

class EdgeAddAction: public EdgeAction{
public:
	EdgeAddAction( int edgeID, int from, int to, QString edgeLabel = "", bool isUninteresting = false );
	//!< Constructor. Needs all relevant information about the Edge.
	virtual ~EdgeAddAction(){}
	//!< Destructor.
// 	virtual bool isUninteresting()const{ return m_isUninteresting; }
	virtual void exec( ActionCommunicator *communicator );
	//!< exec will inform AlgorithmVisualizer of the new Edge.
private:
// 	bool m_isUninteresting;
};//!< Action to show an Edge was added to Graph.

class EdgeRemoveAction: public EdgeAction{
public:
	EdgeRemoveAction( int edgeID, int from, int to, QString edgeLabel = "" );
	//!< Constructor. Only edgeID should be necessary.
	virtual ~EdgeRemoveAction(){}
	//!< Destructor.
	virtual void exec( ActionCommunicator *communicator );
	//!< Exec will inform AlgorithmVisualizer of this Edge being removed.
private:
};//!< Action to show an Edge was removed from Graph

class EdgeHighlightAction: public EdgeAction{
public:
	EdgeHighlightAction( int edgeID );
	//!< Constructor. Only the edgeID of the Edge to be highlighted is sufficient.
	virtual ~EdgeHighlightAction(){}
	//!< Destructor.
	virtual void exec( ActionCommunicator *communicator );
	//!< Exec will have this Edge highlighted.
private:
	
};//!< Action to highlight an Edge.

class EdgeUnHighlightAction: public EdgeAction{
public:
	EdgeUnHighlightAction(int edgeID);
	//!< Constructor. edgeID is sufficient to identify the Edge.
	virtual ~EdgeUnHighlightAction() {}
	//!< Destructor.
	virtual void exec( ActionCommunicator *communicator );
	//!< Exec will make sure this Edge is unhighlighted and if possible restore its previous colour.
};//!< Action to unhighlight an Edge.

class ContainerRemoveAction: public Action{
public:
	ContainerRemoveAction( int containerID );
	//!< Constructor. Only requires ID of the Container.
	virtual ~ContainerRemoveAction(){}
	//!< Destructor.
	virtual void exec( ActionCommunicator *communicator );
	//!< Informs GUI of Container being removed.
	bool isUninteresting()const{ return true; }
	//!< No need to halt after this Action.
private:
	int m_containerID;//!< ID of Container to be removed.
};//!< Action to show a container was removed.

class ContainerElementAction: public Action{
public:
	ContainerElementAction( int container, int element );
	//!< Constructor. Needs identifier for container and element.
	virtual ~ContainerElementAction(){}
	//!< Destructor.
	void setContainer( int container ){ m_container = container; }
	//!< Set Container on which this Action is performed.
	void setElement( int element ){ m_element = element; }
	//!< Set ContainerElement on which this Action is performed.
protected:
	int m_container;//!< Container on which this Action is performed.
	int m_element;//!< Index of ContainerElement in Container on which this Action is performed.
};//!< Base class for Actions on ContainerElements

class ContainerElementAddAction: public ContainerElementAction{
public:
	ContainerElementAddAction( int container, int element );
	//!< Constructor. Takes id for container and the location where it was added.
	virtual ~ContainerElementAddAction(){}
	//!< Destructor.
	bool isUninteresting()const{ return true; }
	//!< This is not considered interesting, because something relevant should be added to this ContainerElement soon.
	virtual void exec( ActionCommunicator *communicator );
	//!< Inform ContainerVisualizer of a new ContainerElement.
private:
};//!< Action to show a ContainerElement was added to Container.

class ContainerElementRemoveAction: public ContainerElementAction{
public:
	ContainerElementRemoveAction( int container, int element );
	//!< Constructor. Needs to know which container and which element.
	virtual ~ContainerElementRemoveAction(){}
	//!< Destructor.
	bool isUninteresting()const{ return true; }
	//!< This type of Action we won't consider interesting.
	virtual void exec( ActionCommunicator *communicator );
	//!< Inform ContainerVisualizer to remove this ContainerElement.
private:
};//!< Action to show a ContainerElement was removed from its Container.

class ContainerElementSetNodeAction: public ContainerElementAction{
public:
	ContainerElementSetNodeAction( int container, int element, int nodeID, QString nodeLabel = "" );
	//!< Constructor. Needs idenfitication for ContainerElement and Node.
	virtual ~ContainerElementSetNodeAction(){}
	//!< Destructor.
	virtual void exec( ActionCommunicator *communicator );
	//!< Inform ContainerVisualizer to show a Node in this ContainerElement.
private:
	int m_nodeID;
	QString m_nodeLabel;
};//!< Action to set a Node into a ContainerElement.

class ContainerElementRemoveNodeAction: public ContainerElementAction{
public:
	ContainerElementRemoveNodeAction( int container, int element, int nodeID, QString nodeLabel = "" );
	//!< Constructor. Needs all info about ContainerElement and Node.
	virtual ~ContainerElementRemoveNodeAction(){}
	//!< Destructor.
	virtual void exec( ActionCommunicator *communicator );
	//!< Informs ContainerVisualizer to remove Node from ContainerElement.
private:
	int m_nodeID;
	QString m_nodeLabel;
};//!< Action to remove a Node from a ContainerElement.

class ContainerElementSetEdgeAction: public ContainerElementAction{
public:
	ContainerElementSetEdgeAction( int container, int element, int edgeID, int from, int to, QString edgeLabel = "" );
	//!< Constructor. Needs all information about ContainerElement and Edge.
	virtual ~ContainerElementSetEdgeAction(){}
	//!< Destructor.
	virtual void exec( ActionCommunicator *communicator );
	//!< Inform ContainerVisualizer to show an Edge in this ContainerElement.
private:
	int m_id;
	int m_from;
	int m_to;
	QString m_edgeLabel;
};//!< Action to set an Edge into a ContainerElement.

class ContainerElementRemoveEdgeAction: public ContainerElementAction{
public:
	ContainerElementRemoveEdgeAction( int container, int element, int edgeID, int from, int to, QString edgeLabel = "" );
	//!< Constructor. Takes all data about ContainerElement and Edge.
	virtual ~ContainerElementRemoveEdgeAction(){}
	//!< Destructor.
	virtual void exec( ActionCommunicator *communicator );
	//!< Informs ContainerElement of Edge removal.
private:
	int m_id;
	int m_from;
	int m_to;
	QString m_edgeLabel;
};//!< Action to remove an Edge from a ContainerElement.

class ContainerElementSetDataAction: public ContainerElementAction{
public:
	ContainerElementSetDataAction( int container, int element, QString data );
	//!< Constructor. Needs idenfication for ContainerElement and the data to show as QString.
	virtual ~ContainerElementSetDataAction(){}
	//!< Destructor.
	virtual void exec( ActionCommunicator *communicator );
	//!< Inform ContainerVisualizer to show this data in given ContainerElement.
private:
	QString m_data;
};//!< Action to set data into a ContainerElement.

class CommentAction: public Action{
public:
	CommentAction( QString comment );
	//!< Constructor. Needs only know the comment.
	virtual ~CommentAction(){}
	//!< Destructor.
	bool isUninteresting()const{ return true; }
	//!< Uninteresting, because right after this comment, another action should halt the program.
	virtual void exec( ActionCommunicator *communicator );
	//!< Display the comment.
private:
	QString m_comment;
};//!< Action to output a comment to the interface.

#endif
/*! @} */